#include "sshsession.h"
#include <QDebug>
#include <QHostAddress>
#include <QNetworkInterface>
#include <QTimer>
#include <QDir>
#include <QFileInfo>
#include <QProcessEnvironment>

#ifdef Q_OS_WIN
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#endif

SshSession::SshSession(const SshManager::ConnectionConfig &config, const QString &sessionId, QObject *parent)
    : QThread(parent)
    , m_config(config)
    , m_sessionId(sessionId)
    , m_state(Disconnected)
    , m_sshSession(nullptr)
    , m_shellChannel(nullptr)
    , m_sftpSession(nullptr)
    , m_socket(-1)
    , m_running(false)
    , m_keepAliveTimer(nullptr)
{
}

SshSession::~SshSession()
{
    // 确保线程已停止
    if (isRunning()) {
        m_running = false;
        wait();
    }

    // 清理资源
    cleanup();
}

bool SshSession::connectTo()
{
    if (m_state == Connected || m_state == Ready) {
        return true;
    }

    setState(Connecting);

    // 启动连接线程
    m_running = true;
    start();

    return true;
}

void SshSession::disconnect()
{
    if (m_state == Disconnected) {
        return;
    }

    setState(Disconnected);
    m_running = false;

    // 触发线程退出
    if (isRunning()) {
        wait(5000); // 等待最多5秒
    }

    cleanup();
    setState(Disconnected);
}

bool SshSession::isConnected() const
{
    return m_state == Ready;
}

SshSession::SessionState SshSession::state() const
{
    return m_state;
}

bool SshSession::authenticateWithPassword(const QString &password)
{
    if (!m_sshSession || m_state != Authenticating) {
        return false;
    }

    // 使用密码认证（阻塞模式测试）
    QByteArray username_bytes = m_config.username.toUtf8();
    QByteArray password_bytes = password.toUtf8();

    const char *username = username_bytes.constData();
    const char *pass = password_bytes.constData();

    qDebug() << "Starting password authentication for" << m_sessionId;
    qDebug() << "Username length:" << username_bytes.length() << "Password length:" << password_bytes.length();

    int rc = libssh2_userauth_password(m_sshSession, username, pass);
    qDebug() << "Password auth returned" << rc << "for" << m_sessionId;

    if (rc == 0) {
        setState(Authenticated);
        qDebug() << "Password authentication successful for" << m_sessionId;
        return true;
    }

    char *errmsg = nullptr;
    libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
    QString error_msg = QString("Password authentication failed: %1 (code: %2)").arg(errmsg ? errmsg : "Unknown error").arg(rc);
    qDebug() << "Password auth error for" << m_sessionId << "-" << error_msg;
    setLastError(error_msg);
    return false;
}

bool SshSession::authenticateWithKey(const QString &privateKeyPath, const QString &passphrase)
{
    if (!m_sshSession || m_state != Authenticating) {
        return false;
    }

    // 检查私钥文件是否存在
    QFileInfo keyFile(privateKeyPath);
    if (!keyFile.exists()) {
        setLastError(QString("Private key file not found: %1").arg(privateKeyPath));
        return false;
    }

    // 使用公钥认证
    QByteArray username_bytes = m_config.username.toUtf8();
    QByteArray keyPath_bytes = privateKeyPath.toUtf8();
    QByteArray passphrase_bytes = passphrase.toUtf8();

    const char *username = username_bytes.constData();
    const char *keyPath = keyPath_bytes.constData();
    const char *pass = passphrase_bytes.isEmpty() ? nullptr : passphrase_bytes.constData();

    qDebug() << "Trying public key auth with key:" << privateKeyPath << "passphrase empty:" << passphrase.isEmpty();

    int rc = libssh2_userauth_publickey_fromfile(m_sshSession, username, nullptr, keyPath, pass);
    if (rc == 0) {
        setState(Authenticated);
        qDebug() << "Public key authentication successful for" << m_sessionId;
        return true;
    }

    char *errmsg = nullptr;
    libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
    QString error_msg = QString("Public key authentication failed: %1 (code: %2)").arg(errmsg ? errmsg : "Unknown error").arg(rc);
    qDebug() << "Public key auth failed for" << m_sessionId << "-" << error_msg;
    setLastError(error_msg);
    return false;
}

bool SshSession::openShell()
{
    if (!m_sshSession || m_state != Authenticated) {
        return false;
    }

    // 创建shell通道
    m_shellChannel = libssh2_channel_open_session(m_sshSession);
    if (!m_shellChannel) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to open shell channel: %1").arg(errmsg));
        return false;
    }

    // 请求伪终端
    int rc = libssh2_channel_request_pty(m_shellChannel, "xterm-256color");
    if (rc != 0) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to request PTY: %1").arg(errmsg));
        libssh2_channel_free(m_shellChannel);
        m_shellChannel = nullptr;
        return false;
    }

    // 启动shell
    rc = libssh2_channel_shell(m_shellChannel);
    if (rc != 0) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to start shell: %1").arg(errmsg));
        libssh2_channel_free(m_shellChannel);
        m_shellChannel = nullptr;
        return false;
    }

    // 设置非阻塞模式
    libssh2_channel_set_blocking(m_shellChannel, 0);

    setState(Ready);
    return true;
}

bool SshSession::executeCommand(const QString &command, QString &output)
{
    if (!m_sshSession || m_state != Authenticated) {
        return false;
    }

    // 创建执行通道
    LIBSSH2_CHANNEL *channel = libssh2_channel_open_session(m_sshSession);
    if (!channel) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to open channel: %1").arg(errmsg));
        return false;
    }

    // 执行命令
    const char *cmd = command.toUtf8().constData();
    int rc = libssh2_channel_exec(channel, cmd);
    if (rc != 0) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to execute command: %1").arg(errmsg));
        libssh2_channel_free(channel);
        return false;
    }

    // 读取输出
    output.clear();
    char buffer[4096];
    ssize_t nread;

    while ((nread = libssh2_channel_read(channel, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[nread] = '\0';
        output += QString::fromUtf8(buffer);
    }

    // 等待命令完成
    while (libssh2_channel_eof(channel) == 0) {
        waitForSession(100);
    }

    // 获取退出码
    int exitcode = libssh2_channel_get_exit_status(channel);

    // 关闭通道
    libssh2_channel_free(channel);

    return exitcode == 0;
}

bool SshSession::sendShellCommand(const QString &command)
{
    if (!m_shellChannel || m_state != Ready) {
        return false;
    }

    QString fullCommand = command + "\n";
    const char *cmd = fullCommand.toUtf8().constData();
    size_t len = strlen(cmd);

    ssize_t nwritten = libssh2_channel_write(m_shellChannel, cmd, len);
    return nwritten == static_cast<ssize_t>(len);
}

bool SshSession::sendShellData(const QByteArray &data)
{
    qDebug() << "sendShellData called, state:" << m_state << "has shell channel:" << (m_shellChannel != nullptr);

    if (!m_shellChannel || (m_state != Authenticated && m_state != Ready)) {
        qDebug() << "sendShellData rejected - no shell channel or wrong state";
        return false;
    }

    ssize_t nwritten = libssh2_channel_write(m_shellChannel, data.constData(), data.size());
    qDebug() << "sendShellData wrote" << nwritten << "bytes out of" << data.size();
    return nwritten == data.size();
}

bool SshSession::openSftp()
{
    if (!m_sshSession || m_state != Authenticated) {
        return false;
    }

    // 初始化SFTP会话
    m_sftpSession = libssh2_sftp_init(m_sshSession);
    if (!m_sftpSession) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to initialize SFTP: %1").arg(errmsg));
        return false;
    }

    // 设置非阻塞模式
    libssh2_session_set_blocking(m_sshSession, 0);

    return true;
}

bool SshSession::closeSftp()
{
    if (m_sftpSession) {
        libssh2_sftp_shutdown(m_sftpSession);
        m_sftpSession = nullptr;
    }
    return true;
}

QList<SshSession::SftpFile> SshSession::listDirectory(const QString &path)
{
    QList<SftpFile> files;

    if (!m_sftpSession) {
        return files;
    }

    // 打开目录
    LIBSSH2_SFTP_HANDLE *dir = libssh2_sftp_opendir(m_sftpSession, path.toUtf8().constData());
    if (!dir) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to open directory: %1").arg(errmsg));
        return files;
    }

    // 读取目录内容
    LIBSSH2_SFTP_ATTRIBUTES attrs;
    char buffer[512];
    char longentry[512];
    ssize_t rc;

    while ((rc = libssh2_sftp_readdir(dir, buffer, sizeof(buffer), &attrs)) > 0) {
        buffer[rc] = '\0';

        // 跳过当前目录和上级目录
        if (strcmp(buffer, ".") == 0 || strcmp(buffer, "..") == 0) {
            continue;
        }

        SftpFile file = sftpAttributesToFile(path + "/" + buffer, &attrs);
        files.append(file);
    }

    // 关闭目录
    libssh2_sftp_close(dir);

    return files;
}

bool SshSession::uploadFile(const QString &localPath, const QString &remotePath)
{
    if (!m_sftpSession) {
        return false;
    }

    // 打开本地文件
    QFile localFile(localPath);
    if (!localFile.open(QIODevice::ReadOnly)) {
        setLastError(QString("Failed to open local file: %1").arg(localPath));
        return false;
    }

    // 创建远程文件
    LIBSSH2_SFTP_HANDLE *remoteFile = libssh2_sftp_open(m_sftpSession, remotePath.toUtf8().constData(),
                                                        LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC,
                                                        0644);
    if (!remoteFile) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to create remote file: %1").arg(errmsg));
        localFile.close();
        return false;
    }

    // 上传文件内容
    char buffer[4096];
    qint64 totalRead = 0;
    qint64 fileSize = localFile.size();

    while (!localFile.atEnd()) {
        qint64 bytesRead = localFile.read(buffer, sizeof(buffer));
        if (bytesRead > 0) {
            ssize_t bytesWritten = libssh2_sftp_write(remoteFile, buffer, bytesRead);
            if (bytesWritten < 0) {
                char *errmsg = nullptr;
                libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
                setLastError(QString("Failed to write to remote file: %1").arg(errmsg));
                libssh2_sftp_close(remoteFile);
                localFile.close();
                return false;
            }
            totalRead += bytesWritten;

            // 发送进度信号
            emit fileTransferProgress(localPath, totalRead, fileSize);
        }
    }

    // 关闭文件
    libssh2_sftp_close(remoteFile);
    localFile.close();

    return true;
}

bool SshSession::downloadFile(const QString &remotePath, const QString &localPath)
{
    if (!m_sftpSession) {
        return false;
    }

    // 打开远程文件
    LIBSSH2_SFTP_HANDLE *remoteFile = libssh2_sftp_open(m_sftpSession, remotePath.toUtf8().constData(),
                                                        LIBSSH2_FXF_READ, 0);
    if (!remoteFile) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to open remote file: %1").arg(errmsg));
        return false;
    }

    // 创建本地文件
    QFile localFile(localPath);
    if (!localFile.open(QIODevice::WriteOnly)) {
        setLastError(QString("Failed to create local file: %1").arg(localPath));
        libssh2_sftp_close(remoteFile);
        return false;
    }

    // 获取远程文件大小
    LIBSSH2_SFTP_ATTRIBUTES attrs;
    if (libssh2_sftp_fstat(remoteFile, &attrs) == 0) {
        emit fileTransferProgress(remotePath, 0, attrs.filesize);
    }

    // 下载文件内容
    char buffer[4096];
    qint64 totalRead = 0;

    while (true) {
        ssize_t bytesRead = libssh2_sftp_read(remoteFile, buffer, sizeof(buffer));
        if (bytesRead < 0) {
            char *errmsg = nullptr;
            libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
            setLastError(QString("Failed to read from remote file: %1").arg(errmsg));
            libssh2_sftp_close(remoteFile);
            localFile.close();
            localFile.remove();
            return false;
        }

        if (bytesRead == 0) {
            break; // 文件结束
        }

        if (localFile.write(buffer, bytesRead) < 0) {
            setLastError(QString("Failed to write to local file: %1").arg(localFile.errorString()));
            libssh2_sftp_close(remoteFile);
            localFile.close();
            localFile.remove();
            return false;
        }

        totalRead += bytesRead;
        emit fileTransferProgress(remotePath, totalRead, attrs.filesize);
    }

    // 关闭文件
    libssh2_sftp_close(remoteFile);
    localFile.close();

    return true;
}

bool SshSession::deleteFile(const QString &remotePath)
{
    if (!m_sftpSession) {
        return false;
    }

    int rc = libssh2_sftp_unlink(m_sftpSession, remotePath.toUtf8().constData());
    if (rc != 0) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to delete file: %1").arg(errmsg));
        return false;
    }

    return true;
}

bool SshSession::createDirectory(const QString &path)
{
    if (!m_sftpSession) {
        return false;
    }

    int rc = libssh2_sftp_mkdir(m_sftpSession, path.toUtf8().constData(), 0755);
    if (rc != 0) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to create directory: %1").arg(errmsg));
        return false;
    }

    return true;
}

bool SshSession::removeDirectory(const QString &path)
{
    if (!m_sftpSession) {
        return false;
    }

    int rc = libssh2_sftp_rmdir(m_sftpSession, path.toUtf8().constData());
    if (rc != 0) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to remove directory: %1").arg(errmsg));
        return false;
    }

    return true;
}

bool SshSession::renameFile(const QString &oldPath, const QString &newPath)
{
    if (!m_sftpSession) {
        return false;
    }

    int rc = libssh2_sftp_rename(m_sftpSession, oldPath.toUtf8().constData(), newPath.toUtf8().constData());
    if (rc != 0) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        setLastError(QString("Failed to rename file: %1").arg(errmsg));
        return false;
    }

    return true;
}

QString SshSession::sessionId() const
{
    return m_sessionId;
}

QString SshSession::host() const
{
    return m_config.host;
}

int SshSession::port() const
{
    return m_config.port;
}

QString SshSession::username() const
{
    return m_config.username;
}

QString SshSession::lastError() const
{
    return m_lastError;
}

void SshSession::run()
{
    // 设置线程优先级
    setPriority(QThread::TimeCriticalPriority);

    qDebug() << "SSH session thread started for" << m_sessionId;

    if (!createSocket()) {
        qDebug() << "Socket creation failed for" << m_sessionId << "-" << m_lastError;
        setState(Error);
        return;
    }
    qDebug() << "Socket created successfully for" << m_sessionId;

    if (!initializeSession()) {
        qDebug() << "Session initialization failed for" << m_sessionId << "-" << m_lastError;
        setState(Error);
        return;
    }
    qDebug() << "Session initialized successfully for" << m_sessionId;

    if (!handshake()) {
        qDebug() << "Handshake failed for" << m_sessionId << "-" << m_lastError;
        setState(Error);
        return;
    }
    qDebug() << "Handshake successful for" << m_sessionId;

    if (!authenticate()) {
        qDebug() << "Authentication failed for" << m_sessionId << "-" << m_lastError;
        setState(Error);
        return;
    }
    qDebug() << "Authentication successful for" << m_sessionId;

    setState(Authenticated);

    // 启动keepalive定时器
    if (m_config.keepAlive) {
        m_keepAliveTimer = new QTimer();
        m_keepAliveTimer->setParent(this);
        connect(m_keepAliveTimer, &QTimer::timeout, this, &SshSession::keepAlive, Qt::QueuedConnection);
        m_keepAliveTimer->start(30000); // 30秒间隔
    }

    // 主循环 - 处理shell输入输出
    qDebug() << "Starting main loop, state:" << m_state << "running:" << m_running;
    while (m_running && (m_state == Ready || m_state == Authenticated)) {
        processShellOutput();
        msleep(10); // 避免CPU占用过高
    }
    qDebug() << "Exiting main loop, state:" << m_state << "running:" << m_running;

    qDebug() << "SSH session thread ended for" << m_sessionId;
}

void SshSession::keepAlive()
{
    if (m_sshSession) {
        libssh2_keepalive_send(m_sshSession, 0);
    }
}

bool SshSession::createSocket()
{
#ifdef Q_OS_WIN
    // 初始化Winsock
    WSADATA wsaData;
    int rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (rc != 0) {
        setLastError("WSAStartup failed");
        return false;
    }
#endif

    // 创建socket
    m_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (m_socket == -1) {
        setLastError("Failed to create socket");
        return false;
    }

    // 设置非阻塞模式
#ifdef Q_OS_WIN
    u_long mode = 1;
    ioctlsocket(m_socket, FIONBIO, &mode);
#else
    int flags = fcntl(m_socket, F_GETFL, 0);
    fcntl(m_socket, F_SETFL, flags | O_NONBLOCK);
#endif

    // 解析主机地址
    struct addrinfo hints = {};
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    struct addrinfo *result = nullptr;
    int resolve_result = getaddrinfo(m_config.host.toUtf8().constData(), QString::number(m_config.port).toUtf8().constData(), &hints, &result);
    if (resolve_result != 0) {
        setLastError(QString("Failed to resolve hostname: %1").arg(gai_strerror(resolve_result)));
        closesocket(m_socket);
        m_socket = -1;
        return false;
    }

    // 连接到服务器
    int connect_result = ::connect(m_socket, result->ai_addr, result->ai_addrlen);
    if (connect_result == -1) {
#ifdef Q_OS_WIN
        int error = WSAGetLastError();
        if (error != WSAEWOULDBLOCK) {
            setLastError(QString("Failed to connect: %1").arg(error));
            closesocket(m_socket);
            m_socket = -1;
            freeaddrinfo(result);
            return false;
        }
#else
        if (errno != EINPROGRESS) {
            setLastError(QString("Failed to connect: %1").arg(strerror(errno)));
            closesocket(m_socket);
            m_socket = -1;
            freeaddrinfo(result);
            return false;
        }
#endif
    }

    freeaddrinfo(result);

    // 等待连接完成
    fd_set write_set;
    FD_ZERO(&write_set);
    FD_SET(m_socket, &write_set);

    struct timeval timeout;
    timeout.tv_sec = m_config.timeout;
    timeout.tv_usec = 0;

    int select_result = select(m_socket + 1, nullptr, &write_set, nullptr, &timeout);
    if (select_result < 0) {
#ifdef Q_OS_WIN
        int error = WSAGetLastError();
        setLastError(QString("Select error: %1").arg(error));
#else
        setLastError(QString("Select error: %1").arg(strerror(errno)));
#endif
        closesocket(m_socket);
        m_socket = -1;
        return false;
    } else if (select_result == 0) {
        setLastError("Connection timeout");
        closesocket(m_socket);
        m_socket = -1;
        return false;
    }

    // 检查连接错误
    int error = 0;
    socklen_t len = sizeof(error);
    getsockopt(m_socket, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
    if (error != 0) {
#ifdef Q_OS_WIN
        char error_msg[256];
        FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                       nullptr, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                       error_msg, sizeof(error_msg), nullptr);
        setLastError(QString("Connection failed: %1").arg(error_msg));
#else
        setLastError(QString("Connection failed: %1").arg(strerror(error)));
#endif
        closesocket(m_socket);
        m_socket = -1;
        return false;
    }

    return true;
}

bool SshSession::initializeSession()
{
    // 创建libssh2会话
    m_sshSession = libssh2_session_init();
    if (!m_sshSession) {
        setLastError("Failed to initialize SSH session");
        return false;
    }

    // 临时使用阻塞模式进行测试
    libssh2_session_set_blocking(m_sshSession, 1);

    return true;
}

bool SshSession::handshake()
{
    // 执行SSH握手（阻塞模式测试）
    qDebug() << "Starting SSH handshake (blocking mode) for" << m_sessionId;

    int rc = libssh2_session_handshake(m_sshSession, m_socket);
    qDebug() << "Handshake returned" << rc << "for" << m_sessionId;

    if (rc == 0) {
        qDebug() << "Handshake successful for" << m_sessionId;
    } else {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        QString error_msg = QString("SSH handshake failed: %1 (code: %2)").arg(errmsg).arg(rc);
        qDebug() << "Handshake error for" << m_sessionId << "-" << error_msg;
        setLastError(error_msg);
        return false;
    }

    // 获取服务器主机密钥
    const char *fingerprint = libssh2_hostkey_hash(m_sshSession, LIBSSH2_HOSTKEY_HASH_SHA1);
    if (!fingerprint) {
        setLastError("Failed to get host key fingerprint");
        return false;
    }

    // 这里可以添加主机密钥验证逻辑
    // 暂时跳过验证，实际应用中应该验证主机密钥

    return true;
}

bool SshSession::authenticate()
{
    setState(Authenticating);

    // 获取认证方法列表
    qDebug() << "Getting authentication methods for user:" << m_config.username;
    const char *auth_methods = libssh2_userauth_list(m_sshSession, m_config.username.toUtf8().constData(), m_config.username.length());
    if (!auth_methods) {
        char *errmsg = nullptr;
        libssh2_session_last_error(m_sshSession, &errmsg, nullptr, 0);
        QString error = QString("Failed to get authentication methods: %1").arg(errmsg);
        qDebug() << error;
        setLastError(error);
        return false;
    }

    QString available_methods = QString(auth_methods);
    qDebug() << "Available authentication methods:" << available_methods;

    // 尝试不同的认证方法
    QStringList methods = available_methods.split(',');

    // 1. 首先尝试密码认证（最常用）
    if (methods.contains("password") && !m_config.password.isEmpty()) {
        qDebug() << "Trying password authentication";
        if (authenticateWithPassword(m_config.password)) {
            return true;
        }
    }

    // 2. 尝试公钥认证
    if (methods.contains("publickey") && !m_config.privateKeyPath.isEmpty()) {
        qDebug() << "Trying public key authentication with:" << m_config.privateKeyPath;
        if (authenticateWithKey(m_config.privateKeyPath, "")) {
            return true;
        }
    }

    // 3. 尝试键盘交互认证（如果服务器支持）- 暂时禁用
    // if (methods.contains("keyboard-interactive")) {
    //     qDebug() << "Trying keyboard-interactive authentication";
    //     if (authenticateWithKeyboardInteractive()) {
    //         return true;
    //     }
    // }

    // 4. 最后尝试SSH代理认证 - 暂时禁用
    // if (methods.contains("publickey")) {
    //     qDebug() << "Trying SSH agent authentication";
    //     if (authenticateWithAgent()) {
    //         return true;
    //     }
    // }

    QString error = "No supported authentication method available. Server supports: " + available_methods;
    qDebug() << error;
    setLastError(error);
    return false;
}

void SshSession::cleanup()
{
    // 清理shell通道
    if (m_shellChannel) {
        libssh2_channel_close(m_shellChannel);
        libssh2_channel_free(m_shellChannel);
        m_shellChannel = nullptr;
    }

    // 清理SFTP会话
    if (m_sftpSession) {
        libssh2_sftp_shutdown(m_sftpSession);
        m_sftpSession = nullptr;
    }

    // 清理SSH会话
    if (m_sshSession) {
        libssh2_session_disconnect(m_sshSession, "Goodbye");
        libssh2_session_free(m_sshSession);
        m_sshSession = nullptr;
    }

    // 关闭socket
    if (m_socket != -1) {
        closesocket(m_socket);
        m_socket = -1;
    }

#ifdef Q_OS_WIN
    // 清理Winsock
    WSACleanup();
#endif

    // 清理定时器
    if (m_keepAliveTimer) {
        m_keepAliveTimer->stop();
        delete m_keepAliveTimer;
        m_keepAliveTimer = nullptr;
    }
}

void SshSession::setState(SessionState state)
{
    if (m_state != state) {
        m_state = state;
        emit stateChanged(state);

        switch (state) {
        case Connected:
            emit connected();
            break;
        case Disconnected:
            emit disconnected();
            break;
        case Ready:
            emit connected();
            break;
        case Error:
            emit error(m_lastError);
            break;
        default:
            break;
        }
    }
}

void SshSession::setLastError(const QString &error)
{
    m_lastError = error;
    qWarning() << "SSH session error:" << m_sessionId << "-" << error;
}

void SshSession::processShellOutput()
{
    if (!m_shellChannel) {
        return;
    }

    // 检查通道是否已关闭
    if (libssh2_channel_eof(m_shellChannel)) {
        qDebug() << "Shell channel EOF, disconnecting";
        setState(Disconnected);
        return;
    }

    // 读取shell输出
    char buffer[4096];
    ssize_t nread;
    bool hasOutput = false;

    while ((nread = libssh2_channel_read(m_shellChannel, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[nread] = '\0';
        qDebug() << "Shell output:" << nread << "bytes";
        emit shellOutput(QByteArray(buffer, nread));
        hasOutput = true;
    }

    // 读取错误输出
    while ((nread = libssh2_channel_read_stderr(m_shellChannel, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[nread] = '\0';
        qDebug() << "Shell error:" << nread << "bytes";
        emit shellError(QByteArray(buffer, nread));
        hasOutput = true;
    }

    // 检查是否有数据等待写入
    int window = libssh2_channel_window_write(m_shellChannel);
    if (window > 0) {
        // 可以发送更多数据
    }
}

int SshSession::waitForSocket(int timeout_ms)
{
    fd_set fd;
    fd_set fd_write;
    fd_set fd_error;
    FD_ZERO(&fd);
    FD_SET(m_socket, &fd);
    FD_ZERO(&fd_write);
    FD_SET(m_socket, &fd_write);
    FD_ZERO(&fd_error);
    FD_SET(m_socket, &fd_error);

    struct timeval tv;
    tv.tv_sec = timeout_ms / 1000;
    tv.tv_usec = (timeout_ms % 1000) * 1000;

    return select(m_socket + 1, &fd, &fd_write, &fd_error, &tv);
}

int SshSession::waitForSession(int timeout_ms)
{
    return waitForSocket(timeout_ms);
}

LIBSSH2_SFTP_ATTRIBUTES* SshSession::getSftpAttributes(const QString &path)
{
    if (!m_sftpSession) {
        return nullptr;
    }

    LIBSSH2_SFTP_ATTRIBUTES *attrs = new LIBSSH2_SFTP_ATTRIBUTES();
    if (libssh2_sftp_stat(m_sftpSession, path.toUtf8().constData(), attrs) != 0) {
        delete attrs;
        return nullptr;
    }

    return attrs;
}

SshSession::SftpFile SshSession::sftpAttributesToFile(const QString &path, const LIBSSH2_SFTP_ATTRIBUTES *attrs)
{
    SftpFile file;
    file.path = path;
    file.name = QFileInfo(path).fileName();
    file.size = attrs->filesize;
    file.isDirectory = LIBSSH2_SFTP_S_ISDIR(attrs->permissions);
    file.lastModified = QDateTime::fromTime_t(attrs->mtime);
    file.permissions = QString::number(attrs->permissions, 8).right(3);

    return file;
}
